package com.hongru.ums.controller.api;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.hongru.constant.CommonConstant;
import com.hongru.constant.DictConstant;
import com.hongru.ebean.EbeanUtil;
import com.hongru.mms.entity.MmsSiteMessageMember;
import com.hongru.redis.util.RedisUtil;
import com.hongru.system.entity.SysLbs;
import com.hongru.ums.entity.UmsLikeRecord;
import com.hongru.ums.entity.UmsMember;
import com.hongru.ums.entity.UmsMemberLoginLog;
import com.hongru.ums.entity.vo.UmsMemberVo;
import com.hongru.ums.util.EmojiUtil;
import com.hongru.util.BeanUtil;
import com.hongru.util.CommonUtils;
import com.hongru.util.JwtUtil;
import com.hongru.vo.LoginUser;
import com.hongru.vo.Result;
import io.ebean.ExpressionList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @Copyright (c) 1998-2022 北京新鸿儒世纪网络技术有限公司 All Rights Reserved.
 * @Url https://www.xinhongru.com
 * @ClassName LoginController
 * @Author salter <salter@vip.163.com>
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2022/3/31 10:04
 */
@RestController
@RequestMapping("/ums/wx")
@Slf4j
@Api(tags = "微信小程序相关接口")
public class UmsWxMaController {
    private final RedisUtil redisUtil;
    protected WxMaDefaultConfigImpl config;
    protected WxMaService wxMaService;

    @Value(value = "${wx.miniapp.appId}")
    private String appId;
    @Value(value = "${wx.miniapp.secret}")
    private String secret;

    public UmsWxMaController(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    public void init() {
        config = new WxMaDefaultConfigImpl();
        config.setAppid(appId);
        config.setSecret(secret);
        wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);
    }


    @GetMapping(value = "/miniAppLogin")
    @ApiOperation(value = "小程序登录接口")
    public Result miniAppLogin(String code) {
        init();
        UmsMember member = new UmsMember();
        String name = EbeanUtil.initExpressionList(SysLbs.class).findList().get(0).getName();
        member.setAddress(name);
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            String openid = sessionInfo.getOpenid();
            ExpressionList<UmsMember> el = EbeanUtil.initExpressionList(UmsMember.class).eq("openId", openid);
            //是否存在此用户
            if (el.findCount() > 0) {
                member = el.findOne();
            } else {
                member.setOpenId(openid);
                member.save();
            }
            //执行授权方法
            // 生成token
            String token = JwtUtil.sign(member.getId(), member.getId(), "UmsMember");
            //小程序sessionKey缓存
            redisUtil.set("ums:member:sessionKey" + member.getId(), sessionInfo.getSessionKey());
            // 设置token缓存有效时间
            redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
            redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
            UmsMemberVo umsMemberVo = BeanUtil.copy(member, UmsMemberVo.class);
            int count = EbeanUtil.initExpressionList(MmsSiteMessageMember.class).eq("memberId", umsMemberVo.getId()).eq("status", DictConstant.READ_STATUS_0).findCount();
            int collectCount = EbeanUtil.initExpressionList(UmsLikeRecord.class).eq("memberId", umsMemberVo.getId()).eq("operation", DictConstant.LIKE_OPERATION_COLLECT).findCount();
            umsMemberVo.setCollectCount(collectCount);
            umsMemberVo.setMsgCount(count);
            umsMemberVo.setToken(token);
            //记录登陆日志
            UmsMemberLoginLog memberLoginLog = new UmsMemberLoginLog();
            memberLoginLog.setMemberId(member.getId());
            memberLoginLog.save();
            return Result.OK(umsMemberVo);
        } catch (WxErrorException e) {
            return Result.OK();
        }
    }

    @PostMapping(value = "/getUserProfile")
    @ApiOperation(value = "名称头像授权接口")
    public Result getUserProfile(@RequestBody UmsMember member) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        member.setId(loginUser.getId());
        member.setNickName(EmojiUtil.filterEmoji(member.getNickName()));
        member.setAuth(true);
        member.update();
        return Result.OK();
    }

    @PostMapping(value = "/getPhoneNumber")
    @ApiOperation(value = "手机号授权接口")
    @ApiOperationSupport(params = @DynamicParameters(properties = {
            @DynamicParameter(name = "code", value = "code", example = ""),
            @DynamicParameter(name = "encryptedData", value = "encryptedData", example = ""),
            @DynamicParameter(name = "iv", value = "iv", example = ""),
    }))
    public Result getPhoneNumber(@RequestBody JSONObject jsonObject) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        init();
        String sessionKey = redisUtil.get("ums:member:sessionKey" + loginUser.getId()).toString();
        String encryptedData = jsonObject.getString("encryptedData");
        String iv = jsonObject.getString("iv");
        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        UmsMember member = new UmsMember();
        member.setId(loginUser.getId());
        member.setPhone(phoneNoInfo.getPhoneNumber());
        member.update();
        return Result.OK(phoneNoInfo.getPhoneNumber());
    }

    @PostMapping(value = "/getwxacodeunlimit")
    @ApiOperation(value = "获取小程序码")
    @ApiOperationSupport(params = @DynamicParameters(properties = {
            @DynamicParameter(name = "scene", value = "scene", example = "id=1"),
            @DynamicParameter(name = "page", value = "page", example = "pages/index/index"),
    }))
    public Result getwxacodeunlimit(@RequestBody JSONObject jsonObject) {
        init();
        String page = jsonObject.getString("page");
        String scene = jsonObject.getString("scene");
        try {
            File wxaCodeUnlimit = wxMaService.getQrcodeService().createWxaCodeUnlimit(scene, page);
            MultipartFile cMultiFile = new MockMultipartFile("file", wxaCodeUnlimit.getName(), null, new FileInputStream(wxaCodeUnlimit));
            String savePath = CommonUtils.upload(cMultiFile, "", CommonConstant.UPLOAD_TYPE_LOCAL);
            return Result.OK(savePath);
        } catch (Exception e) {

        }
        return Result.OK();
    }


    @GetMapping
    @ApiOperation(value = "发送订阅消息")
    public Result send() {
        init();
        List<WxMaSubscribeMessage.MsgData> list = new ArrayList<>();
        WxMaSubscribeMessage.MsgData msgData1 = new WxMaSubscribeMessage.MsgData();
        msgData1.setName("thing1");
        msgData1.setValue("课程开始啦");
        list.add(msgData1);
        WxMaSubscribeMessage.MsgData msgData2 = new WxMaSubscribeMessage.MsgData();
        msgData2.setName("time2");
        msgData2.setValue("2022-04-19");
        list.add(msgData2);
        WxMaSubscribeMessage.MsgData msgData3 = new WxMaSubscribeMessage.MsgData();
        msgData3.setName("thing3");
        msgData3.setValue("温馨提示");
        list.add(msgData3);

        WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage();
        subscribeMessage.setTemplateId("-GDEWUbVy9X43sq2RZ83qWzk1SvddueEXxzZUjrwJS4");
        subscribeMessage.setToUser("oN16f5DGjJ56spPbdw3GDaRpRq0I");
        subscribeMessage.setData(list);
        try {
            wxMaService.getSubscribeService().sendSubscribeMsg(subscribeMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        return Result.OK();
    }


}
